#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.GamerServices;
using KLib.Graphics;
#endregion

namespace KLib.Utilities
{
    /// <summary>
    /// A Wrapper to put around a Game to display unhandled exeptions to the Screen.
    /// It also allows the user to Exit the game, and not have their PC/Xbox crash.
    /// </summary>
    public class ExeptionGame : Game
    {
        #region Fields
        readonly Exception exeption;
        GamerServicesComponent gamerService;
        SpriteRenderer spriteBatch;
        SpriteFont font;

        string errorMessage = string.Empty;
        Texture2D backGround;
        Vector2 safeRegionOffset;
        #endregion

        #region Properties

        #endregion

        #region Initialization

        public ExeptionGame(Exception e)
            : base()
        {
            this.exeption = e;
            new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void LoadContent()
        {
            font = Content.Load<SpriteFont>("Fonts/errorFont");
            base.LoadContent();
            spriteBatch = new SpriteRenderer(this.GraphicsDevice);

            string stack = exeption.StackTrace;
            try
            {
                stack = stack.Remove(stack.IndexOf("\n"));
            }
            catch { }
            try
            {

                stack = stack.Substring(stack.IndexOf("Projects") + 8);
            }
            catch { }

            errorMessage = "*****CRASH LOG******\nAn unhandled " + this.exeption.GetType().ToString() + " has occured:\n" + this.exeption.Message + "\n The error occured at " + exeption.TargetSite + "\n @ " + stack;
            TextureGenerator.Initalize(this.GraphicsDevice);
            backGround = TextureGenerator.GenerateRectangle(800, 600, Color.Black);

            SafeRegionComponent safe = new SafeRegionComponent(this);
            safe.Initialize();
            this.Components.Add(safe);

            safeRegionOffset = new Vector2(GraphicsDevice.Viewport.Width * 0.08f, GraphicsDevice.Viewport.Height * 0.08f);

#if !XBOX
            System.IO.File.AppendAllText("crashlog.txt", DateTime.Now + "\n" + errorMessage);
#endif
        }

        #endregion

        #region Methods
        protected override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            if (Microsoft.Xna.Framework.Input.GamePad.GetState(PlayerIndex.One).IsButtonDown(Microsoft.Xna.Framework.Input.Buttons.Back)
                || Microsoft.Xna.Framework.Input.Keyboard.GetState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape))
                this.Exit();
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend,SpriteSortMode.Immediate,SaveStateMode.None);
            //spriteBatch.Draw(backGround, Vector2.Zero, Color.White);
            spriteBatch.DrawString(font,errorMessage, safeRegionOffset,Color.White);
            //spriteBatch.DrawWrappedString(font,errorMessage, new Rectangle(100, 100, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height));
#if XBOX
            spriteBatch.DrawString(font, "Press 'Back' to Exit to Dashboard", safeRegionOffset + new Vector2(GraphicsDevice.Viewport.Width / 2f - font.MeasureString("Press 'Back' to Exit to Dashboard").X,font.MeasureString(errorMessage).Y + font.LineSpacing * 2), Color.White);
#else
            spriteBatch.DrawString(font, "Press 'Escape' to Exit", safeRegionOffset + new Vector2(GraphicsDevice.Viewport.Width / 2f - font.MeasureString("Press 'Escape' to Exit").X,font.MeasureString(errorMessage).Y + font.LineSpacing * 2), Color.White);
#endif
            spriteBatch.End();

            base.Draw(gameTime);
        }
        #endregion

        #region Helper Methods

        #endregion
    }
}
